/*
 * LoginController.java  2011-11-10 
 * 
 * Copyright (c) 2011, Sohu.com All Rights Reserved. 
 *
 * (Description about the file)
 */
package com.fuershiye.woman.monitor.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;

/**
 * @author yongyongdong
 *
 */
@Slf4j
@Controller
@RequestMapping("/")
public class LoginController {

    @RequestMapping(value="login.do",method=RequestMethod.GET)
    public String login(HttpServletRequest request){

        // 如果用户没有退出，则先登出
        Subject subject = SecurityUtils.getSubject();
        if(subject.getSession()!=null){
            SecurityUtils.getSubject().logout();
        }
        if(subject.isAuthenticated()){
            return getIndex(request);
        }
        return "login";
    }

    @RequestMapping(value="login.do",method=RequestMethod.POST)
    public String userLogin(@RequestParam(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM) String username, String password, Model model) {

//            前端提交的密码，因为是明文，而从数据库取出的数据是密文，所以在验证的时候，也应该把明文转化为相应的密文然后进行比对。
//            首先前台提交的用户名和密码会被封装到UsernamePasswordToken里面
//            接着调用SecurityUtils.getSubject(),获取subject对象
//            调用subject.login()方法
//            将登录的验证交给自定义的类UserRealm,此类实现了AuthorizingRealm接口，并且重写了doGetAuthenticationInfo(AuthenticationToken arg0)方法
//            arg0是subject.login(token)，传递过来的token 该方法的返回值是一个SimpleAuthenticationInfo对象。
//            并且此对象具有四个参数，从左到右依次是：身份，从数据库取出来的明文密码，加密明文所用的盐对象（ByteResource），最后是此Realm的名称。
//            因为接下来shiro要做的是，密码比对，此时前台传过来的密码是明文，因此需要转换成密文，
//            但此时，我们并没有告诉Realm我们加密使用的算法以及加密的次数，因此接着要做的是去applicationContext.xml中配置UserRealm的属性。
//            下面是代码：详见 applicationContext-shiro.xml
//    <bean id="shiroRealm2" class="com.fuershiye.woman.monitor.shiro.realm.ShiroRealm">
//        <property name="credentialsMatcher" ref="credentialsMatcher" />
//        <property name="cachingEnabled" value="true" />
//        <property name="authenticationCachingEnabled" value="true" />
//        <property name="authenticationCacheName" value="authenticationCache" />
//        <property name="authorizationCachingEnabled" value="false" />
//        <property name="authorizationCacheName" value="authorizationCache" />
//    </bean>

        log.info("username:{}", username);
        model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username);
  	    UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(true);
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(token);//不明白的是他怎么匹配密码的?我没告诉他那个是正确的password,那个是username.
        } catch (UnknownAccountException uae) {
            log.info("账户不存在,{}",username);
            return "login";
        }
//      catch (IncorrectCredentialsException ice) {
//          System.out.println("密码不正确!");
//        return "login";
//      }
        catch (LockedAccountException lae) {
            log.info("账户被禁了,{}",username);
            return "login";
        } catch (AuthenticationException ae) {
            log.info("认证错误,{}",username);
            return "login";
        }
        return "home";
    }
    
    @RequestMapping(value="index.do")
    public String index(HttpServletRequest request){
        return "home";
    }

    @RequestMapping(value="noPermission.do",method=RequestMethod.GET)
    public String errornoPermission(){

        return "views/manager/noPermission";
    }

    @RequestMapping(value="unauthorized.do",method=RequestMethod.GET)
    public String unauthorized(){

        return "views/manager/noPermission";
    }

    private String getIndex(HttpServletRequest request){
        String path = request.getContextPath();
        int port = request.getServerPort();
        String basePath ="";
        if(port==80){
            basePath = "http://"+request.getServerName()+path+"/";
        }else{
            basePath = "http://"+request.getServerName()+":"+request.getServerPort()+path+"/";
        }
        return "redirect:"+basePath+"index.do";
    }

}
